package initialize

import (
	"encoding/json"
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/nacos-group/nacos-sdk-go/clients"
	"github.com/nacos-group/nacos-sdk-go/common/constant"
	"github.com/nacos-group/nacos-sdk-go/vo"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"lz/global"
)

func GetEnvInfo(env string) bool {
	fmt.Println(env)
	viper.AutomaticEnv()
	return viper.GetBool(env)
}

// 用viper 操作配置文件
func InitConfig() {

	isEnv := GetEnvInfo("IS_DEV")

	file := "config/config-pro.yaml"
	//如果本地测试读取本地配置
	if isEnv == true {
		file = "config/config-debug.yaml"
	}

	//初始化viper 并且设置配置文件地址 之后读取配置文件使其生效
	v := viper.New()
	v.SetConfigFile(fmt.Sprintf("%s", file))
	if err := v.ReadInConfig(); err != nil {
		zap.S().Errorf("读取配置文件失败%s", err)
		return
	}
	//反解config 配置文件读取所有配置
	if err := v.Unmarshal(global.ServerConfig); err != nil {
		zap.S().Errorf("Unmarshal 配置文件失败%s", err)
		return
	}
	//监听配置配置文件实时变化实时生效
	v.WatchConfig()
	v.OnConfigChange(func(in fsnotify.Event) {
		zap.S().Infof("配置文件变化为:%s", in.Name)

		_ = v.ReadInConfig()
		_ = v.Unmarshal(global.ServerConfig)
		zap.S().Info("读取配置文件变化为&v")
	})
}

// nacos
func InitNacosConfig() {

	//初始化viper
	v := viper.New()

	//检测环境变量查看是否为测试环境走不同的配置文件
	isDebug := GetEnvInfo("IS_DEV")
	file := "config/nacos-pro.yaml"
	if isDebug == true {
		file = "config/nocos-dev.yaml"
	}

	//设置配置文件路径 并读取
	v.SetConfigFile(file)
	if err := v.ReadInConfig(); err != nil {

		zap.S().Errorf("读取配置文件失败%s", err)
		return

	}

	//反解nacos配置
	if err := v.Unmarshal(&global.NacosConfig); err != nil {

		zap.S().Errorf("nacos转换结构体失败%s", err)
		return
	}

	//初始化nacos配置 并定义不少于一个nacos 服务配置
	sc := []constant.ServerConfig{
		{
			IpAddr: global.NacosConfig.Host,
			Port:   global.NacosConfig.Port,
		},
	}
	//定一个nacos客户端连接配置
	cc := constant.ClientConfig{
		NamespaceId:         global.NacosConfig.NamespaceId, // 如果需要支持多namespace，我们可以场景多个client,它们有不同的NamespaceId
		TimeoutMs:           5000,
		NotLoadCacheAtStart: true,
		LogDir:              "tmp/nacos/log",
		CacheDir:            "tmp/nacos/cache",
		//RotateTime:          "1h",
		//MaxAge:              3,
		LogLevel: "debug",
	}
	//连接naccos
	cl, err := clients.NewConfigClient(vo.NacosClientParam{
		ClientConfig:  &cc,
		ServerConfigs: sc,
	})
	if err != nil {
		zap.S().Errorf("连接[Nacos]失败，出错原因%s", err)
		return
	}

	//获取NaCos 配置信息
	content, err := cl.GetConfig(vo.ConfigParam{
		DataId: global.NacosConfig.DataId,
		Group:  global.NacosConfig.Group,
	})
	if err != nil {
		return

	}
	//反解naccos配置信息 因为Nacos 配置为json 格式顾使用 json.Unmarshal
	if err := json.Unmarshal([]byte(content), &global.ServerConfig); err != nil {
		return
	}

	//我们配置一个Nacos 监听信息使配置实时生效
	go func() {
		cl.ListenConfig(vo.ConfigParam{
			DataId: global.NacosConfig.DataId,
			Group:  global.NacosConfig.Group,
			OnChange: func(namespace string, group string, dataId string, data string) {

				//日志记录配置信息变化
				zap.S().Infof("命名空间变更为:%s,分组变更为:%s,配置文件变更为:%s", namespace, dataId, group)
				if err := json.Unmarshal([]byte(data), &global.ServerConfig); err != nil {

					zap.S().Error("反解[Nacos]配置信息失败出错原因%s", err)
					return
				}
			},
		})
	}()
}
